import '../../domain/entities/anime.dart';
import '../../domain/repositories/anime_repository.dart';
import '../datasources/anime_remote_datasource.dart';
import '../datasources/anime_local_datasource.dart';

/// 动漫数据仓库实现
/// 结合远程API和本地缓存
class AnimeRepositoryImpl implements AnimeRepository {
  final AnimeRemoteDataSource _remoteDataSource;
  final AnimeLocalDataSource _localDataSource;

  AnimeRepositoryImpl({
    required AnimeRemoteDataSource remoteDataSource,
    required AnimeLocalDataSource localDataSource,
  }) : _remoteDataSource = remoteDataSource,
       _localDataSource = localDataSource;

  @override
  Future<List<Anime>> getTopAnime({
    int page = 1,
    String filter = 'bypopularity',
    int limit = 25,
  }) async {
    try {
      // 首先尝试从缓存获取
      final cacheKey = 'top_anime_${filter}_${page}_$limit';
      final cachedData = await _localDataSource.getCachedAnimeList(cacheKey);
      
      if (cachedData.isNotEmpty) {
        return cachedData.map((model) => model.toEntity()).toList();
      }

      // 缓存无数据，从远程获取
      final remoteData = await _remoteDataSource.getTopAnime(
        page: page,
        filter: filter,
        limit: limit,
      );

      // 缓存数据
      await _localDataSource.cacheAnimeList(cacheKey, remoteData);

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      // 如果网络失败，尝试返回缓存数据（即使过期）
      final cacheKey = 'top_anime_${filter}_${page}_$limit';
      final cachedData = await _localDataSource.getCachedAnimeList(
        cacheKey, 
        ignoreExpiry: true,
      );
      
      if (cachedData.isNotEmpty) {
        return cachedData.map((model) => model.toEntity()).toList();
      }
      
      rethrow;
    }
  }

  @override
  Future<List<Anime>> searchAnime({
    required String query,
    int page = 1,
    String? type,
    String? status,
    String? genre,
  }) async {
    try {
      // 搜索结果通常不缓存，直接从远程获取
      final remoteData = await _remoteDataSource.searchAnime(
        query: query,
        page: page,
        type: type,
        status: status,
        genre: genre,
      );

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      rethrow;
    }
  }

  @override
  Future<Anime> getAnimeDetails(int animeId) async {
    try {
      // 首先从缓存获取详情
      final cachedData = await _localDataSource.getCachedAnimeDetails(animeId);
      
      if (cachedData != null) {
        return cachedData.toEntity();
      }

      // 缓存无数据，从远程获取
      final remoteData = await _remoteDataSource.getAnimeDetails(animeId);

      // 缓存详情数据
      await _localDataSource.cacheAnimeDetails(remoteData);

      return remoteData.toEntity();
    } catch (e) {
      // 网络失败时尝试返回过期缓存
      final cachedData = await _localDataSource.getCachedAnimeDetails(
        animeId, 
        ignoreExpiry: true,
      );
      
      if (cachedData != null) {
        return cachedData.toEntity();
      }
      
      rethrow;
    }
  }

  @override
  Future<List<Anime>> getAnimeRecommendations(int animeId) async {
    try {
      final remoteData = await _remoteDataSource.getAnimeRecommendations(animeId);
      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      rethrow;
    }
  }

  @override
  Future<List<Anime>> getSeasonalAnime({
    int? year,
    String season = 'now',
    int page = 1,
    bool forceRefresh = false,
  }) async {
    try {
      final cacheKey = 'seasonal_anime_${year ?? 'current'}_${season}_$page';
      
      // 如果不是强制刷新，优先从缓存加载
      if (!forceRefresh) {
      final cachedData = await _localDataSource.getCachedAnimeList(
        cacheKey,
        preferCache: true,
      );
      
      if (cachedData.isNotEmpty) {
        // 后台刷新数据
        _refreshSeasonalAnimeInBackground(year, season, page, cacheKey);
        return cachedData.map((model) => model.toEntity()).toList();
        }
      }

      // 从远程获取
      final remoteData = await _remoteDataSource.getSeasonalAnime(
        year: year,
        season: season,
        page: page,
      );

      // 缓存数据
      await _localDataSource.cacheAnimeList(cacheKey, remoteData);

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      // 网络失败时返回缓存
      final cacheKey = 'seasonal_anime_${year ?? 'current'}_${season}_$page';
      final cachedData = await _localDataSource.getCachedAnimeList(
        cacheKey, 
        ignoreExpiry: true,
      );
      
      if (cachedData.isNotEmpty) {
        return cachedData.map((model) => model.toEntity()).toList();
      }
      
      rethrow;
    }
  }

  /// 后台刷新当季动漫数据
  void _refreshSeasonalAnimeInBackground(int? year, String season, int page, String cacheKey) {
    Future.delayed(const Duration(milliseconds: 500), () async {
      try {
        final remoteData = await _remoteDataSource.getSeasonalAnime(
          year: year,
          season: season,
          page: page,
        );
        await _localDataSource.cacheAnimeList(cacheKey, remoteData);
        print('后台刷新当季动漫数据成功');
      } catch (e) {
        print('后台刷新当季动漫数据失败: $e');
      }
    });
  }

  @override
  Future<List<Anime>> getUpcomingAnime({
    int page = 1,
    int limit = 5,
    bool forceRefresh = false,
  }) async {
    try {
      final cacheKey = 'upcoming_anime_${page}_$limit';
      
      // 如果不是强制刷新，优先从缓存加载
      if (!forceRefresh) {
      final cachedData = await _localDataSource.getCachedAnimeList(
        cacheKey,
        preferCache: true,
      );
      
      if (cachedData.isNotEmpty) {
        // 后台刷新数据
        _refreshUpcomingAnimeInBackground(page, limit, cacheKey);
        return cachedData.map((model) => model.toEntity()).toList();
        }
      }

      // 从远程获取
      final remoteData = await _remoteDataSource.getUpcomingAnime(
        page: page,
        limit: limit,
      );

      // 缓存数据
      await _localDataSource.cacheAnimeList(cacheKey, remoteData);

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      rethrow;
    }
  }

  /// 后台刷新即将上线动漫数据
  void _refreshUpcomingAnimeInBackground(int page, int limit, String cacheKey) {
    Future.delayed(const Duration(milliseconds: 500), () async {
      try {
        final remoteData = await _remoteDataSource.getUpcomingAnime(
          page: page,
          limit: limit,
        );
        await _localDataSource.cacheAnimeList(cacheKey, remoteData);
        print('后台刷新即将上线动漫数据成功');
      } catch (e) {
        print('后台刷新即将上线动漫数据失败: $e');
      }
    });
  }

  @override
  Future<List<Anime>> getTrendingAnime({
    int page = 1,
    int limit = 20,
    bool forceRefresh = false, // 添加强制刷新参数
  }) async {
    try {
      final cacheKey = 'trending_anime_${page}_$limit';
      
      // 如果不是强制刷新，优先从缓存加载
      if (!forceRefresh) {
      final cachedData = await _localDataSource.getCachedAnimeList(
        cacheKey, 
        preferCache: true,
      );
      
      if (cachedData.isNotEmpty) {
        // 后台刷新数据
        _refreshTrendingAnimeInBackground(page, limit, cacheKey);
        return cachedData.map((model) => model.toEntity()).toList();
        }
      }

      // 从远程获取（强制刷新或缓存为空）
      final remoteData = await _remoteDataSource.getTrendingAnime(
        page: page,
        limit: limit,
      );

      // 缓存数据
      await _localDataSource.cacheAnimeList(cacheKey, remoteData);

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      // 如果出错，尝试返回过期的缓存数据
      final cacheKey = 'trending_anime_${page}_$limit';
      final cachedData = await _localDataSource.getCachedAnimeList(
        cacheKey, 
        ignoreExpiry: true,
      );
      
      if (cachedData.isNotEmpty) {
        return cachedData.map((model) => model.toEntity()).toList();
      }
      
      rethrow;
    }
  }

  /// 后台刷新热门动漫数据
  void _refreshTrendingAnimeInBackground(int page, int limit, String cacheKey) {
    Future.delayed(const Duration(milliseconds: 500), () async {
      try {
        final remoteData = await _remoteDataSource.getTrendingAnime(
          page: page,
          limit: limit,
        );
        await _localDataSource.cacheAnimeList(cacheKey, remoteData);
        print('后台刷新热门动漫数据成功');
      } catch (e) {
        print('后台刷新热门动漫数据失败: $e');
      }
    });
  }

  @override
  Future<List<Anime>> getAnimeByGenre({
    required int genreId,
    int page = 1,
    int limit = 20,
  }) async {
    try {
      // 分类动漫缓存
      final cacheKey = 'genre_anime_${genreId}_${page}_$limit';
      final cachedData = await _localDataSource.getCachedAnimeList(cacheKey);
      
      if (cachedData.isNotEmpty) {
        return cachedData.map((model) => model.toEntity()).toList();
      }

      // 从远程获取
      final remoteData = await _remoteDataSource.getAnimeByGenre(
        genreId: genreId,
        page: page,
        limit: limit,
      );

      // 缓存数据
      await _localDataSource.cacheAnimeList(cacheKey, remoteData);

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      rethrow;
    }
  }

  @override
  Future<List<Anime>> getAnimeByStatus({
    required String status,
    int page = 1,
    int limit = 20,
  }) async {
    try {
      // 状态动漫缓存
      final cacheKey = 'status_anime_${status}_${page}_$limit';
      final cachedData = await _localDataSource.getCachedAnimeList(cacheKey);
      
      if (cachedData.isNotEmpty) {
        return cachedData.map((model) => model.toEntity()).toList();
      }

      // 从远程获取
      final remoteData = await _remoteDataSource.getAnimeByStatus(
        status: status,
        page: page,
        limit: limit,
      );

      // 缓存数据
      await _localDataSource.cacheAnimeList(cacheKey, remoteData);

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      rethrow;
    }
  }

  @override
  Future<List<Anime>> getAnimeByType({
    required String type,
    int page = 1,
    int limit = 20,
  }) async {
    try {
      // 类型动漫缓存
      final cacheKey = 'type_anime_${type}_${page}_$limit';
      final cachedData = await _localDataSource.getCachedAnimeList(cacheKey);
      
      if (cachedData.isNotEmpty) {
        return cachedData.map((model) => model.toEntity()).toList();
      }

      // 从远程获取
      final remoteData = await _remoteDataSource.getAnimeByType(
        type: type,
        page: page,
        limit: limit,
      );

      // 缓存数据
      await _localDataSource.cacheAnimeList(cacheKey, remoteData);

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      rethrow;
    }
  }

  @override
  Future<List<Anime>> getRecentEpisodes({
    int limit = 15,
    bool forceRefresh = false,
  }) async {
    try {
      final cacheKey = 'recent_episodes_$limit';
      
      // 如果不是强制刷新，优先从缓存加载
      if (!forceRefresh) {
      final cachedData = await _localDataSource.getCachedAnimeList(
        cacheKey,
        preferCache: true,
      );
      
      if (cachedData.isNotEmpty) {
        // 后台刷新数据
          _refreshRecentEpisodesInBackground(limit, cacheKey);
        return cachedData.map((model) => model.toEntity()).toList();
        }
      }

      // 从远程获取
      final remoteData = await _remoteDataSource.getRecentEpisodes(
        limit: limit,
      );

      // 缓存数据，但缓存时间较短
      await _localDataSource.cacheAnimeList(cacheKey, remoteData);

      return remoteData.map((model) => model.toEntity()).toList();
    } catch (e) {
      // 网络失败时尝试返回缓存数据
      final cacheKey = 'recent_episodes_$limit';
      final cachedData = await _localDataSource.getCachedAnimeList(
        cacheKey, 
        ignoreExpiry: true,
      );
      
      if (cachedData.isNotEmpty) {
        return cachedData.map((model) => model.toEntity()).toList();
      }
      
      rethrow;
    }
  }

  /// 后台刷新最新剧集数据
  void _refreshRecentEpisodesInBackground(int limit, String cacheKey) {
    Future.delayed(const Duration(milliseconds: 500), () async {
      try {
        final remoteData = await _remoteDataSource.getRecentEpisodes(
          limit: limit,
        );
        await _localDataSource.cacheAnimeList(cacheKey, remoteData);
        print('后台刷新最新剧集数据成功');
      } catch (e) {
        print('后台刷新最新剧集数据失败: $e');
      }
    });
  }

  @override
  Future<void> clearCache() async {
    await _localDataSource.clearCache();
  }

  @override
  Future<Map<String, dynamic>> getCacheStatus() async {
    return await _localDataSource.getCacheInfo();
  }
} 